#ifndef __HASH_TABLE
#define __HASH_TABLE


typedef struct nodo {
	void *info;
	struct nodo *prox;
}NODO;

struct hash_table {
    int tamanho;
    int ocupados;
    unsigned int	(*hash)		(void *);
    void *		(*getKey)	(void *);
    int 		(*compKey)	(void *,void *);
    NODO **table;
};


typedef struct hash_table HASH_TABLE;

/**
 * @fn hash_table_apagar
 * @brief Apaga um utilizador da tabela de hash
 * @param hash_point Estrutura da tabela de hash

 */

int hash_table_apagar(HASH_TABLE *hash_point);

/**
 * @fn hash_table_ocupados
 * @brief Verifica se uma tabela esta vazia
 * @param hash_point Estrutura da tabela de hash
 */

int hash_table_ocupados(HASH_TABLE *hash_point);

/**
 * @fn hash_table_inserir
 * @brief Insere um utilizador da tabela de hash
 * @param hash_point Estrutura da tabela de hash
 * @param str Nome do utilizador a inserir
 * @param inf Informacao do utilizador a inserir
 */
int hash_table_inserir (HASH_TABLE *, void* );

/**
 * @fn hash_table_init
 * @brief Inicializa a tabela de hash
 * @param hash Apontador para a estrutura que armazena a tabela de hash
 */
int hash_table_init 					(
	HASH_TABLE **hash					,
	int tamanho							,
	unsigned int funcao_hash(void *)	,
	void *	(*getKey)	(void *)		,
	int		(*compKey)	(void *,void *)	);

/**
 * @fn hash_table_procura
 * @brief Procura um utilizador da tabela de hash
 * @param hash_point Estrutura da tabela de hash
 * @param key chave a pesquisar na tabela
 */
void* hash_table_procura (HASH_TABLE *, void *);

/**@fn hash_table_remover
 * @brief Remove um utilizador da tabela de hash
 * @param hash_point Estrutura da tabela de hash
 * @param str Nome do utilizador a remover
 */
int hash_table_remover (HASH_TABLE *, void *);

/**
 * @fn hash_table_map
 * @brief Funcao que aplica uma dada funcao a tabela de hash //map em Haskell
 * @param hash_point Estrutura da tabela de hash
 * @param f Função a aplicar, deve retornar 0 em sucesso, e 1 noutros casos
 * @param params
 */

int hash_table_map	(HASH_TABLE *hash_point, int (*f)(void *, void *), void *params);


/*
 MELHOR FUNÇAO DE HASH PARA STRINGS:

 unsigned long
 hash(unsigned char *str)
 {
 unsigned long hash = 5381;
 int c;

 while (c = *str++)
 hash = ((hash << 5) + hash) + c; /* hash * 33 + c

return hash;
}*/

#endif